/*-----------------------------------------------File Info------------------------------------------------
** File Name:               serialFlash.c  
** Last modified date:      2016.07.22
** Last version:            V0.1
** Description:             
**--------------------------------------------------------------------------------------------------------            
** Created date:            2016.09.07
** author:                  YLY
** Version:                 V0.1
** Descriptions:            串行闪存器
**--------------------------------------------------------------------------------------------------------
*/

/*************************************************************
* 	include 
* 	头文件	
*************************************************************/
#include "SerialFlash.h"


uint8_t gManufacturer;		/* 厂商 */
uint8_t ucgSerialFlashType;		/* 型号 */



/*		读芯片ID
 *  说明: 	初始化FLASH
 *	参数:	用于存储ID的指针
 *	返回: 	FAIL OR SUCCESS
 */
void vSerialFlashInit(void)
{		
	spiInit(FLASH_SPI,SPI0_PORT0,SPI_MASTER,1000000U,SPI_MODE2);		/* SPI初始化 */
	
	vSerialFlashWaitBusy();						
	vSerialFlashReadId(&gManufacturer,&ucgSerialFlashType);	/* 读厂商信号和ID */
	if(gManufacturer == FLASH_MANUFACTURER_SST)
	{
		switch(ucgSerialFlashType)
		{
			case FLASH_CHIP_SST25VF040_ID:
			{
				FLASH_PRINTF("NOR FLASH SST 25VF040\r\n");						
			}break;		
			
			case FLASH_CHIP_SST25VF080_ID:	
			{				
				FLASH_PRINTF("NOR FLASH SST 25VF080\r\n");						
			}break;	
			
			case FLASH_CHIP_SST25VF016_ID:	
			{						
				FLASH_PRINTF("NOR FLASH SST 25VF016\r\n");							
			}break;
			
			default:
			{
				gManufacturer = FLASH_CHIP_SST25VF080_ID;
				FLASH_PRINTF("NOR FLASH Id Err\r\n");													
			}break;		
		}
	}
	else if(gManufacturer == FLASH_MANUFACTURER_WINBOND)
	{
		switch(ucgSerialFlashType)
		{
			case FLASH_CHIP_W25Q40_ID:
			{
				FLASH_PRINTF("NOR FLASH WINBOND W25Q40\r\n");						
			}break;		
			
			case FLASH_CHIP_W25Q80_ID:	
			{				
				FLASH_PRINTF("NOR FLASH WINBOND W25Q80\r\n");						
			}break;	
			
			case FLASH_CHIP_W25Q16_ID:	
			{						
				FLASH_PRINTF("NOR FLASH WINBOND W25Q16\r\n");							
			}break;
			
			default:
			{
				gManufacturer = FLASH_CHIP_W25Q80_ID;
				FLASH_PRINTF("NOR FLASH Id Err\r\n");												
			}break;		
		}
	}
	else if(gManufacturer == FLASH_MANUFACTURER_GD)
	{
		switch(ucgSerialFlashType)
		{
			case FLASH_CHIP_W25Q40_ID:
			{
				FLASH_PRINTF("NOR FLASH GD 25Q40\r\n");						
			}break;		
			
			case FLASH_CHIP_W25Q80_ID:	
			{				
				FLASH_PRINTF("NOR FLASH GD 25Q80\r\n");						
			}break;	
			
			case FLASH_CHIP_W25Q16_ID:	
			{						
				FLASH_PRINTF("NOR FLASH GD 25Q16\r\n");							
			}break;
			
			default:
			{
				gManufacturer = FLASH_CHIP_W25Q80_ID;
				FLASH_PRINTF("NOR FLASH Id Err\r\n");				;									
			}break;		
		}		
	}
	else
	{
		gManufacturer = FLASH_MANUFACTURER_WINBOND;	//读不到的芯片,默认为华绑的080
		switch(ucgSerialFlashType)
		{
			case FLASH_CHIP_W25Q40_ID:
			{
				FLASH_PRINTF("NOR FLASH WINBOND W25Q40\r\n");						
			}break;		
			
			case FLASH_CHIP_W25Q80_ID:	
			{				
				FLASH_PRINTF("NOR FLASH WINBOND W25Q80\r\n");						
			}break;	
			
			case FLASH_CHIP_W25Q16_ID:	
			{						
				FLASH_PRINTF("NOR FLASH WINBOND W25Q16\r\n");							
			}break;
			
			default:
			{
				gManufacturer = FLASH_CHIP_W25Q80_ID;
				FLASH_PRINTF("NOR FLASH Id Err\r\n");												
			}break;		
		}	
		FLASH_PRINTF("NOR FLASH Manufacturer Err\r\n");						
	}
}


/*		读芯片ID
 *  说明: 	初始化FLASH
 *	参数:	用于存储ID的指针
 *	返回: 	FAIL OR SUCCESS
 */
void vSerialFlashReadId(uint8_t *pucManufacturer,uint8_t *pucId)
{
	int i;
	
	spiSetNss(FLASH_SPI,NSS_LOW); 
	spiWriteReadByte(FLASH_SPI,RDID_SERIAL_FLASH);  
	spiWriteReadByte(FLASH_SPI,0x00);					/* 通过读厂商ID来判断FLASH通讯是否正常 */
	spiWriteReadByte(FLASH_SPI,0x00);
	spiWriteReadByte(FLASH_SPI,0x00);    
	*pucManufacturer = spiWriteReadByte(FLASH_SPI,0x00);
	FLASH_PRINTF("NOR FLASH pucManufacturer = 0x%x\n",*pucManufacturer);		
	spiSetNss(FLASH_SPI,NSS_HI);
	for(i=0; i<0xf; i++)
		__NOP();
	
	spiSetNss(FLASH_SPI,NSS_LOW);
	spiWriteReadByte(FLASH_SPI,RDID_SERIAL_FLASH);  		
	spiWriteReadByte(FLASH_SPI,0x00);					/* 通过读厂商ID来判断FLASH通讯是否正常 */
	spiWriteReadByte(FLASH_SPI,0x00);
	spiWriteReadByte(FLASH_SPI,0x01);    
	*pucId = spiWriteReadByte(FLASH_SPI,0x00);	
	spiSetNss(FLASH_SPI,NSS_HI);
	FLASH_PRINTF("NOR FLASH id = 0x%x\n",*pucId);
}    

/*-----------------------------------------------------以下常用操作命令函数----------------------------------------------------*/

/*		读状态寄存器
 *  说明: 	初始化FLASH
 *	参数:	无
 *	返回: 	返回状态寄存器的值
 */
uint8_t ucSerialFlashReadStatusRegister(void)                                                                                      
{                                                                                                                         
	uint8_t ucByte;                                                                                        
	spiSetNss(FLASH_SPI,NSS_LOW);                                 	/* enable device */                                                 
	spiWriteReadByte(FLASH_SPI,RDSR_SERIAL_FLASH);    /* send RDSR command */  /* 读状态寄存器指令 */                                        
	ucByte = spiWriteReadByte(FLASH_SPI,0x00);          /* receive byte */                                             
	spiSetNss(FLASH_SPI,NSS_HI);                            	/* disable device */                                               
	return ucByte;                                                                                                   
}

/*		等待空闲
 *  说明: 	在擦除或者编程的时候要检测是否空闲
 *	参数:	无
 *	返回: 	无
 */
void vSerialFlashWaitBusy(void)
{
	uint32_t i=0;
	while(0x03 == (0x03 & ucSerialFlashReadStatusRegister())) 	/* check the BUSY status bit */
	{
		if(i++ > 0xfffff0)	/*MAX 6S*/
			return;
	}
}

/*		使能写状态寄存器
 *  说明: 	用于修改状态寄存器前，解决状态寄存器保护
 *	参数:	无
 *	返回: 	无
 */
void vSerialFlashEwsr(void)                    		/*使能写状态寄存器 */                                                                                       
{                                      	                                                                                   
	spiSetNss(FLASH_SPI,NSS_LOW);                                 			/* enable device */                                                 
	spiWriteReadByte(FLASH_SPI,EWSR_SERIAL_FLASH);  		/* enable writing to the status register */                       
	spiSetNss(FLASH_SPI,NSS_HI);                            			/* disable device */  
}                                                                                                                         


/**		使能写状态寄存器
*  说明: 	用于修改状态寄存器前，解决状态寄存器保护
*	参数:	uint8_t byte: 
*						ENABLE_MODIFY	使能写				
*						DISABLE_MODIFY	禁止写	
*	返回: 	无
**/
void vSerialFlashWrsr(uint8_t byte)      	   /* 写   */                                                                                     
{                                                                                                                         
	spiSetNss(FLASH_SPI,NSS_LOW);                                    /* enable device */                                                 
	spiWriteReadByte(FLASH_SPI,WRSR_SERIAL_FLASH);    /* select write to status register */                             
	spiWriteReadByte(FLASH_SPI,byte);                 /* data that will change the status of BPx or BPL (only bits 2,3,7 can be written) */                              
	spiSetNss(FLASH_SPI,NSS_HI);                              /* disable the device */   
	__NOP();	                                                                                                 
}                                                                                                                         

/*		写数据使能
 *  说明: 	 编程数据前，需要先使能写
 *	参数:	无
 *	返回: 	无
 */
void vSerialFlashWren(void)                                                                                                               
{                                                                                                                         
	spiSetNss(FLASH_SPI,NSS_LOW); 				/* enable device */                                                 
	spiWriteReadByte(FLASH_SPI,WREN_SERIAL_FLASH);   /* send WREN command */                                           
	spiSetNss(FLASH_SPI,NSS_HI);                                 /* disable device */                                               
}                                                                                                                         


/*		写数据禁止
 *  说明: 	 编程完成后,禁止改写数据,防止数据错乱
 *	参数:	无
 *	返回: 	无
 */
void vSerialFlashWrdi(void)                                                                                                               
{                                     
	spiSetNss(FLASH_SPI,NSS_LOW);                                  /* enable device */                                                 
	spiWriteReadByte(FLASH_SPI,WRDI_SERIAL_FLASH);   /* send WRDI command */                                           
	spiSetNss(FLASH_SPI,NSS_HI);                                 /* disable device */                                               
}  





/*----------------------------以下为编程数据-------------------------*/

/**		自动编程A
*  说明: 	地址自动地址增加编程A，需写入首地址
*	参数:	
*		uint32_t uiAddress-> 编程起始地址
*		uint8_t byte1->	第一位数据
*		uint8_t byte2-> 第二位数据
*	返回: 	无
**/
void vSerialFlashAutoAddIncA(uint32_t uiAddress, uint8_t ucByte1,uint8_t ucByte2)                                                                 
{           
	uint8_t  ucAddH,uiAddM,ucAddL;
	
	ucAddH = (uint8_t)(uiAddress >> 16);
	uiAddM = (uint8_t)(uiAddress >>  8);
	ucAddL = (uint8_t)(uiAddress >>  0);
	spiSetNss(FLASH_SPI,NSS_LOW);        								/* enable device */
	spiWriteReadByte(FLASH_SPI,WRITE_AAI_SERIAL_FLASH);   	/* send AAI command  VSerial_FlashB   */                                    
	spiWriteReadByte(FLASH_SPI,ucAddH);    					/* send 3 uiAddress bytes*/	/*最高位*/
	spiWriteReadByte(FLASH_SPI,uiAddM);     				/* 中字节      */                                                       
	spiWriteReadByte(FLASH_SPI,ucAddL); 					/* 最低字节  */
	spiWriteReadByte(FLASH_SPI,ucByte1);            		/* send byte to be programmed */
	spiWriteReadByte(FLASH_SPI,ucByte2);            		/* send byte to be programmed */
	spiSetNss(FLASH_SPI,NSS_HI);                    					/* disable device    */
	__NOP();	
	vSerialFlashWaitBusy();  
}
 
/**		自动编程B
*  说明: 	地址自动地址增加编程A，待执行A将地址写入后，可调用B连续写入数据
*	参数:
*		uint8_t byte1->写入的数据1
*		uint8_t byte2_>写入的数据2
*	返回: 	无
**/
void vSerialFlashAutoAddIncB(uint8_t ucByte1,uint8_t ucByte2)                                                                                    
{                                                                                                                         
	spiSetNss(FLASH_SPI,NSS_LOW);                               		/* enable device */                                           
	spiWriteReadByte(FLASH_SPI,WRITE_AAI_SERIAL_FLASH);  	/* send AAI command VSerial_FlashB*/
	spiWriteReadByte(FLASH_SPI,ucByte1);                    /* send byte to be programmed */
	spiWriteReadByte(FLASH_SPI,ucByte2);                    /* send byte to be programmed */
	spiSetNss(FLASH_SPI,NSS_HI);                              		/* disable device     */ 
	__NOP();	
	vSerialFlashWaitBusy();                                                                                                   
}  	


/**		根据初始化时读取的芯片厂商自动判断连续写的函数
*  说明: 	采用地址自动增加编程方式，数据长度必需能被2整除
*	参数:	
* 		uint32_t uiAddress->编程起始地址
*		uint8_t *databuf->待写入的数据指针
*		uint8_t len->待写入数据的长度
*	返回: 	无
**/
void vSerialFlashWriteBuf(uint32_t uiAddress,uint8_t *pucDataBuf,uint8_t ucLen)  
{
	if(gManufacturer == FLASH_MANUFACTURER_SST)	
	{
		vSerialFlashAutoAddIncBuf(uiAddress,pucDataBuf,ucLen);  
	}
	else
	{
		vSerialFlashWritePageBuf(uiAddress,pucDataBuf,ucLen);  
	}		
}

/**		SST芯片,地址自动增加AAI编程一串数据
*  说明: 	采用地址自动增加编程方式，数据长度必需能被2整除
*	参数:	
* 		uint32_t uiAddress->编程起始地址
*		uint8_t *databuf->待写入的数据指针
*		uint8_t len->待写入数据的长度
*	返回: 	无
**/
void vSerialFlashAutoAddIncBuf(uint32_t uiAddress,uint8_t *pucDataBuf,uint8_t ucLen)  
{
	uint8_t i;
	vSerialFlashEwsr();				/*使能写状态寄存器*/
	__NOP();		
	vSerialFlashWrsr(ENABLE_MODIFY);	/*写状态寄存器-解除块保护*/
	__NOP();	
	vSerialFlashWren();     			/*写使能*/
	vSerialFlashAutoAddIncA(uiAddress,pucDataBuf[0],pucDataBuf[1]);    /*编程一个扇区*/
	for(i=2;i<ucLen;i+=2)
	{
		vSerialFlashAutoAddIncB(pucDataBuf[i],pucDataBuf[i+1]); 
	}
	vSerialFlashWrdi(); 					/*写禁止 */
	__NOP();				
	vSerialFlashEwsr();					/*写状态寄存器*/
	__NOP();				
	vSerialFlashWrsr(DISABLE_MODIFY);       /*BP0,BP1,BP2=1  所有块保护*/
	__NOP();		
}	

/**		非SST的FLASH,采用page编程,连续写数据
*  说明: 	
*	参数:	
*		uiAddress->待写入的地址
*		pucDataBuf->待写入数据
*       ucLen->写入数据的长度
*	返回: 	无
**/
void vSerialFlashWritePageBuf(uint32_t uiAddress,uint8_t *pucDataBuf,uint8_t ucLen)  
{
		uint8_t  ucAddH,uiAddM,ucAddL;
		uint8_t i;
	
		ucAddH = (uint8_t)(uiAddress >> 16);
		uiAddM = (uint8_t)(uiAddress >>  8);
		ucAddL = (uint8_t)(uiAddress >>  0);
	
		vSerialFlashEwsr();							/*使能写状态寄存器*/
		__NOP();	
		vSerialFlashWrsr(ENABLE_MODIFY);				/*写状态寄存器-解除块保护*/
		__NOP();	
		vSerialFlashWren();     						/*写使能  */
		__NOP();	
		spiSetNss(FLASH_SPI,NSS_LOW);        								/* enable device  */
		spiWriteReadByte(FLASH_SPI,WRITE_BYTE_SERIAL_FLASH);  	/*字节编程 */	
	
		spiWriteReadByte(FLASH_SPI,ucAddH);    					/* send 3 uiAddress bytes 最高位*/
		spiWriteReadByte(FLASH_SPI,uiAddM);     				/*中字节  */                                                           
		spiWriteReadByte(FLASH_SPI,ucAddL); 					/*最低字节 */ 
		
		for(i=0;i<ucLen;i++)
		{
			if((uiAddress % 0x100) == 0)	/* 新的一页 */
			{
				if(i>0)	/* 非第一个字节 */
				{
					spiSetNss(FLASH_SPI,NSS_HI);                    					/* disable device  */  
					__NOP();	
					vSerialFlashWaitBusy();  
					
					ucAddH = (uint8_t)(uiAddress >> 16);
					uiAddM = (uint8_t)(uiAddress >>  8);
					ucAddL = (uint8_t)(uiAddress >>  0);					
				
					vSerialFlashWren();     						/*写使能  */
					__NOP();	
					spiSetNss(FLASH_SPI,NSS_LOW);   	
					spiWriteReadByte(FLASH_SPI,WRITE_BYTE_SERIAL_FLASH);  	/*字节编程 */	
					
					spiWriteReadByte(FLASH_SPI,ucAddH);    					/* send 3 uiAddress bytes 最高位*/
					spiWriteReadByte(FLASH_SPI,uiAddM);     				/*中字节  */                                                           
					spiWriteReadByte(FLASH_SPI,ucAddL); 					/*最低字节 */
				}
			} 			
			spiWriteReadByte(FLASH_SPI,pucDataBuf[i]);            		/* send byte to be programmed */
			uiAddress++;
		}
			
		spiSetNss(FLASH_SPI,NSS_HI);                    					/* disable device  */  
		
		__NOP();	
		vSerialFlashWaitBusy();  
		__NOP();	
		vSerialFlashWrdi(); 						 	/*写禁止 */
	
		vSerialFlashEwsr();							/*写状态寄存器*/
		__NOP();	
		vSerialFlashWrsr(DISABLE_MODIFY);        		/*BP0,BP1,BP2=1  所有块保护*/
}	
/**		写一个字节
*  说明: 	写一个字节
*	参数:	
*		uint32_t uiAddress->待写入的地址
*		uint8_t byte->待写入数据
*	返回: 	无
**/
void vSerialFlashWriteByte(uint32_t uiAddress,uint8_t ucByte)  
{
		uint8_t  ucAddH,uiAddM,ucAddL;
		ucAddH = (uint8_t)(uiAddress >> 16);
		uiAddM = (uint8_t)(uiAddress >>  8);
		ucAddL = (uint8_t)(uiAddress >>  0);
	
		vSerialFlashEwsr();							/*使能写状态寄存器*/
		__NOP();	
		vSerialFlashWrsr(ENABLE_MODIFY);				/*写状态寄存器-解除块保护*/
		__NOP();	
		vSerialFlashWren();     						/*写使能  */
		__NOP();	
		spiSetNss(FLASH_SPI,NSS_LOW);        								/* enable device  */
		spiWriteReadByte(FLASH_SPI,WRITE_BYTE_SERIAL_FLASH);  	/*字节编程 */	
	
		spiWriteReadByte(FLASH_SPI,ucAddH);    					/* send 3 uiAddress bytes 最高位*/
		spiWriteReadByte(FLASH_SPI,uiAddM);     				/*中字节  */                                                           
		spiWriteReadByte(FLASH_SPI,ucAddL); 					/*最低字节 */ 
	
		spiWriteReadByte(FLASH_SPI,ucByte);            		/* send byte to be programmed */
		spiSetNss(FLASH_SPI,NSS_HI);                    					/* disable device  */  
		__NOP();	
		vSerialFlashWaitBusy();  
		__NOP();	
		vSerialFlashWrdi(); 						 	/*写禁止 */
	
		vSerialFlashEwsr();							/*写状态寄存器*/
		__NOP();	
		vSerialFlashWrsr(DISABLE_MODIFY);        		/*BP0,BP1,BP2=1  所有块保护*/
}	


/*-------------------------------------------------以下为读FLASH-------------------------------------------*/

/*		读一个Byte数据
 *  说明: 	读一个Byte数据
 *	参数:	uint32_t uiAddress->读取数据的地址
 *	返回: 	此地址的数据
 */
uint8_t ucSerialFlashReadByte(uint32_t uiAddress)  
{
		uint8_t  ucAddH,uiAddM,ucAddL;
		uint8_t ucData;
		ucAddH = (uint8_t)(uiAddress >> 16);
		uiAddM = (uint8_t)(uiAddress >>  8);
		ucAddL = (uint8_t)(uiAddress >>  0);

		spiSetNss(FLASH_SPI,NSS_LOW);        								/* enable device  */
		spiWriteReadByte(FLASH_SPI,READ_SERIAL_FLASH);  		/*	read;*/
		spiWriteReadByte(FLASH_SPI,ucAddH);    				/* send 3 uiAddress bytes 最高位*/
		spiWriteReadByte(FLASH_SPI,uiAddM);     				/*中字节      */                                                       
		spiWriteReadByte(FLASH_SPI,ucAddL); 					/*最低字节  */
	
		ucData = spiWriteReadByte(FLASH_SPI,0x00);            	/* send byte to be programmed */
		spiSetNss(FLASH_SPI,NSS_HI);                    					/* disable device   */
		return ucData;
}	

/**		读多个Byte数据
*  说明: 	读多个Byte数据
*	参数:	
*	uint32_t uiAddress->读取数据的起始地址
*	uint8_t *buf->用于存储读取出的数据指针
*	uint8_t len->读取数据的程度
*	返回: 	无
**/
void vSerialFlashReadBuf(uint32_t uiAddress,uint8_t *pucBuf,uint8_t ucLen)  
{
		uint8_t  ucAddH,uiAddM,ucAddL;
		uint8_t i;
		ucAddH = (uint8_t)(uiAddress >> 16);
		uiAddM = (uint8_t)(uiAddress >>  8);
		ucAddL = (uint8_t)(uiAddress >>  0);

		spiSetNss(FLASH_SPI,NSS_LOW);        									/* enable device */ 
		spiWriteReadByte(FLASH_SPI,READ_SERIAL_FLASH);  			/*	read;*/
		spiWriteReadByte(FLASH_SPI,ucAddH);    					/* send 3 uiAddress bytes	最高位*/
		spiWriteReadByte(FLASH_SPI,uiAddM);     					/*中字节   */                                                          
		spiWriteReadByte(FLASH_SPI,ucAddL); 						/*最低字节  */
		for(i=0;i<ucLen;i++)
		{
				pucBuf[i] = spiWriteReadByte(FLASH_SPI,0x00);        /* send byte to be programmed */
		}
		spiSetNss(FLASH_SPI,NSS_HI);                    						/* disable device */ 
}	

/*		使能连续读
 *  说明: 	使能连续读
 *	参数:	uint32_t uiAddress->读取数据的起始地址
 *	返回: 	无
 */
void vEnableSerialFlashReadByte(uint32_t uiAddress)  
{
		uint8_t  ucAddH,uiAddM,ucAddL;
		ucAddH = (uint8_t)(uiAddress >> 16);
		uiAddM = (uint8_t)(uiAddress >>  8);
		ucAddL = (uint8_t)(uiAddress >>  0);

		spiSetNss(FLASH_SPI,NSS_LOW);        									/* enable device  */
		spiWriteReadByte(FLASH_SPI,READ_SERIAL_FLASH);  			/*	read;*/
		spiWriteReadByte(FLASH_SPI,ucAddH);    					/* send 3 uiAddress bytes	最高位*/
		spiWriteReadByte(FLASH_SPI,uiAddM);     					/*中字节    */                                                         
		spiWriteReadByte(FLASH_SPI,ucAddL); 						/*最低字节  */
}

/*		禁止连续读
 *  说明: 	read:>0读一个字节后停止读
 *	参数:	无
 *	返回: 	无
 */
void vDisableSerialFlashReadByte(void)
{		
		spiWriteReadByte(FLASH_SPI,0x00);	/*使能读后至少读一个字节,避免数据异常*/
		spiSetNss(FLASH_SPI,NSS_HI);  
}



/*-------------------------------------------------以下为数据擦除-------------------------------------------------------------*/

/*		芯片擦除
 *  说明: 	芯片擦除
 *	参数:	无
 *	返回: 	无
 */            
void vSerialFlashChipErase(void)
{	
		vSerialFlashEwsr();							/*使能写状态寄存器*/
		__NOP();
		vSerialFlashWrsr(ENABLE_MODIFY);				/*写状态寄存器-解除块保护*/
		__NOP();	
		vSerialFlashWren();     						/*写使能 */
		__NOP();
		spiSetNss(FLASH_SPI,NSS_LOW);                          				/* enable device*/
		spiWriteReadByte(FLASH_SPI,ERASE_CHIP_SERIAL_FLASH1); /* send Chip Erase command*/
		spiSetNss(FLASH_SPI,NSS_HI);                         				/* disable device */
		__NOP();
		vSerialFlashWaitBusy(); 
		__NOP();	
		vSerialFlashEwsr();							/*写状态寄存器*/
		__NOP();	
		vSerialFlashWrsr(DISABLE_MODIFY);        		/*BP0,BP1,BP2=1  所有块保护*/
		__NOP();
		__NOP();
		__NOP();
		__NOP();
		__NOP();
		__NOP();
}

/*		4K扇区擦除
 *  说明: 	4K扇区擦除
*	参数:	uint32_t uiAddress->擦除的扇区首地址
 *	返回: 	无
 */ 
void vSerialFlashSectorErease4K(uint32_t uiAddress)
{
		uint8_t  ucAddH,uiAddM,ucAddL;
		ucAddH = (uint8_t)(uiAddress >> 16);
		uiAddM = (uint8_t)(uiAddress >>  8);
		ucAddL = (uint8_t)(uiAddress >>  0);
		
		vSerialFlashEwsr();								/*使能写状态寄存器*/
		__NOP();	
		vSerialFlashWrsr(ENABLE_MODIFY);					/*写状态寄存器-解除块保护*/
		__NOP();	
		vSerialFlashWren();     							/*写使能 */
		__NOP();	
		spiSetNss(FLASH_SPI,NSS_LOW);                          					/* enable device*/
		spiWriteReadByte(FLASH_SPI,ERASE_4K_SERIAL_FLASH);        /* send Sector Erase command */
		spiWriteReadByte(FLASH_SPI,ucAddH);    /* send 3 uiAddress bytes*/
		spiWriteReadByte(FLASH_SPI,uiAddM);                                                                           
		spiWriteReadByte(FLASH_SPI,ucAddL);    
		spiSetNss(FLASH_SPI,NSS_HI);                         					/* disable device */
	
		vSerialFlashWaitBusy(); 
		__NOP();	
		vSerialFlashEwsr();								/*写状态寄存器*/
		__NOP();	
		vSerialFlashWrsr(DISABLE_MODIFY);        			/*BP0,BP1,BP2=1  所有块保护*/
}

/*		32K块擦除
 *  说明: 	32K块擦除
 *	参数:	uint32_t uiAddress->擦除的块首地址
 *	返回: 	无
 */ 
void vSerialFlashBlockErease32K(uint32_t uiAddress)
{
		uint8_t  ucAddH,uiAddM,ucAddL;
		ucAddH = (uint8_t)(uiAddress >> 16);
		uiAddM = (uint8_t)(uiAddress >>  8);
		ucAddL = (uint8_t)(uiAddress >>  0);
			
		vSerialFlashEwsr();								/*使能写状态寄存器*/
		__NOP();
		vSerialFlashWrsr(ENABLE_MODIFY);					/*写状态寄存器-解除块保护*/
		__NOP();
		vSerialFlashWren();     							/*写使能*/ 
	
		spiSetNss(FLASH_SPI,NSS_LOW);                          					/* enable device*/
		spiWriteReadByte(FLASH_SPI,ERASE_32K_SERIAL_FLASH);       /* send Sector Erase command */
		spiWriteReadByte(FLASH_SPI,ucAddH);    					/* send 3 uiAddress bytes*/
		spiWriteReadByte(FLASH_SPI,uiAddM);                                                                           
		spiWriteReadByte(FLASH_SPI,ucAddL);    
		spiSetNss(FLASH_SPI,NSS_HI);                         					/* disable device */
	
		vSerialFlashWaitBusy(); 
		__NOP();
		vSerialFlashEwsr();								/*写状态寄存器*/
		__NOP();
		vSerialFlashWrsr(DISABLE_MODIFY);        			/*BP0,BP1,BP2=1  所有块保护*/
}

/*		64K块擦除
 *  说明: 	64K块擦除
 *	参数:	擦出的块地址
 *	返回: 	无
 */ 
void vSerialFlashBlockErease64K(uint32_t uiAddress)
{
		uint8_t  ucAddH,uiAddM,ucAddL;
		ucAddH = (uint8_t)(uiAddress >> 16);
		uiAddM = (uint8_t)(uiAddress >>  8);
		ucAddL = (uint8_t)(uiAddress >>  0);
	
		vSerialFlashEwsr();								/*使能写状态寄存器*/
		__NOP();
		vSerialFlashWrsr(ENABLE_MODIFY);					/*写状态寄存器-解除块保护*/
		__NOP();
		vSerialFlashWren();     							/*写使能 */
	
		spiSetNss(FLASH_SPI,NSS_LOW);                          					/* enable device*/
		spiWriteReadByte(FLASH_SPI,ERASE_64K_SERIAL_FLASH);      	/* send Sector Erase command */
		spiWriteReadByte(FLASH_SPI,ucAddH);    					/* send 3 uiAddress bytes*/
		spiWriteReadByte(FLASH_SPI,uiAddM);                                                                           
		spiWriteReadByte(FLASH_SPI,ucAddL);    
		spiSetNss(FLASH_SPI,NSS_HI);                         					/* disable device */
	
		vSerialFlashWaitBusy(); 
		__NOP();
		vSerialFlashEwsr();								/*写状态寄存器*/
		__NOP();
		vSerialFlashWrsr(DISABLE_MODIFY);        			/*BP0,BP1,BP2=1  所有块保护*/
}      

